/**
 * Created by Admin on 13.06.2015.
 */

(function ($) {

    var GlCamera = $.inherit({

        __constructor: function () {
            this.mvMatrix = mat4.create();
            this.rotationMatrix = mat4.create();
            this.translationMatrix = mat4.create();
            this.xTranslation = 0;
            this.yTranslation = 0;
            this.zTranslation = -3;
            this.rotationXAngle = 0;
            this.rotationYAngle = 0;

        },

        getMovementMatrix: function () {
            return this.mvMatrix;
        },

        _translate: function () {
            var translationMatrix = this.translationMatrix;
            mat4.identity(translationMatrix);
            mat4.translate(this.translationMatrix, [
                this.xTranslation,
                this.yTranslation,
                this.zTranslation
            ]);
            mat4.multiply(translationMatrix, this.mvMatrix, this.mvMatrix);
        },

        _rotate: function () {
            var rotationMatrix = this.rotationMatrix;
            mat4.identity(rotationMatrix);
            mat4.rotate(rotationMatrix, Math.degToRad(this.rotationXAngle), [0, 1, 0]);
            mat4.rotate(rotationMatrix, Math.degToRad(this.rotationYAngle), [1, 0, 0]);
            mat4.multiply(rotationMatrix, this.mvMatrix, this.mvMatrix)
        },

        updateMovementMatrix: function () {
            mat4.identity(this.mvMatrix);
            this._rotate();
            this._translate();
        }

    });

    function getWheelDirection(e) {
        return e.originalEvent.deltaY > 0 ? 1 : -1;
    }

    window.GlCameraControl = $.inherit({

        _bindTranslation: function () {
            var control = this;
            this.$canvas.bind("mousewheel", function (e) {
                control.moveCameraByZ(getWheelDirection(e));
            }).bind("wheel", function (e) {
                control.moveCameraByZ(getWheelDirection(e));
            });
            this._bindClickMouseMove(function (dX, dY, e) {
                var camera = control.selectedCamera;
                if (camera && e.altKey) {
                    camera.xTranslation += dX * control.translationSpeed;
                    camera.yTranslation -= dY * control.translationSpeed;
                }
            })
        },

        _bindClickMouseMove: function (handler) {
            var handleMouseMove = function (e) {
                var x = e.pageX;
                var y = e.pageY;

                var dX = (x - previousX);
                var dY = (y - previousY);
                handler(dX, dY, e);
                previousX = x;
                previousY = y;
            };
            var $canvas = this.$canvas;
            var previousX;
            var previousY;
            var control = this;
            $canvas.bind("mousedown", function (e) {
                previousX = e.pageX;
                previousY = e.pageY;
                $canvas.bind("mousemove", handleMouseMove)
            }).bind("mouseup", function () {
                $canvas.unbind("mousemove", handleMouseMove)
            });
            return control;
        },

        _bindRotation: function () {
            var control = this;
            this._bindClickMouseMove(function (dX, dY, e) {
                var camera = control.selectedCamera;
                if (camera && !e.altKey) {
                    camera.rotationXAngle += dX * control.rotationSpeed;
                    camera.rotationYAngle += dY * control.rotationSpeed;
                }
            });
        },

        addCamera: function (objectId) {
            var camera = new GlCamera;
            this.cameras[objectId] = camera;
            return camera;
        },

        bindDefault: function () {
            var control = this;
            this.$canvas.bind("click", function () {
                control.selectedCamera = null;
            })
        },

        __constructor: function (canvas) {
            this.cameras = {};
            this.translationSpeed = .01;
            this.rotationSpeed = 1;
            this.$canvas = $(canvas);
            this.selectedCamera = null;
            this._bindTranslation();
            this._bindRotation();
            //this.bindDefault();
        },

        moveCameraByZ: function (direction) {
            var camera = this.selectedCamera;
            if(camera){
                camera.zTranslation += direction * this.translationSpeed;
            }
        }

    })

})(window["jQuery"]);